package buaa.qel.rpc.client.loadbalance;

import buaa.qel.rpc.client.handler.RpcClientHandler;
import buaa.qel.rpc.common.info.RegistryNodeInfo;
import buaa.qel.rpc.common.info.RpcServiceInfo;
import buaa.qel.rpc.common.util.ServiceKeyMaker;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.map.HashedMap;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 负载均衡
 */
@Slf4j
public abstract class RpcLoadBalance {
    /**
     * 遍历每个注册信息中的服务信息list，获得服务的接口名称和服务名，通过工具类生成serviceKey（注册时已经生成并保存）
     * 再将每个serviceKey作为键，将注册信息集合作为值，存到表中
     * @param connectedServerNodes
     * @return
     */
    protected Map<String, List<RegistryNodeInfo>> getServiceMap(Map<RegistryNodeInfo, RpcClientHandler> connectedServerNodes) {
        Map<String, List<RegistryNodeInfo>> serviceMap = new HashedMap<>();
        if (connectedServerNodes != null && connectedServerNodes.size() > 0) {
            for (RegistryNodeInfo registryNodeInfo : connectedServerNodes.keySet()) {
                for (RpcServiceInfo serviceInfo : registryNodeInfo.getServiceInfoList()) {
                    String serviceKey = ServiceKeyMaker.makeServiceKey(serviceInfo.getInterfaceName(), serviceInfo.getServiceName());
                    List<RegistryNodeInfo> registryNodeInfos = serviceMap.get(serviceKey);
                    if (registryNodeInfos == null) {
                        registryNodeInfos = new ArrayList<>();
                    }
                    registryNodeInfos.add(registryNodeInfo);
                    serviceMap.putIfAbsent(serviceKey, registryNodeInfos);
                }
            }
        }
        return serviceMap;
    }

    public abstract RegistryNodeInfo route(String serviceKey, Map<RegistryNodeInfo, RpcClientHandler> connectedServerNodes) throws Exception;
}
